package com.vietnam.power.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.vietnam.power.constant.AppConfigurationConstant;
import com.vietnam.power.dao.ApplicationDao;
import com.vietnam.power.dao.ProductDao;
import com.vietnam.power.domain.Product;
import com.vietnam.power.domain.ProductGroup;
import com.vietnam.power.domain.ProductGroupSearchCriteria;
import com.vietnam.power.domain.ProductSearchCriteria;
import com.vietnam.power.persitence.FileUpload;
import com.vietnam.power.persitence.ProductImage;
import com.vietnam.power.persitence.SubProductGroup;
import com.vietnam.power.service.FileService;
import com.vietnam.power.service.ProductService;

@Service
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
public class ProductServiceImpl implements ProductService {

	@Autowired
	private ProductDao productDao;

	@Autowired
	private ApplicationDao applicationDao;

	@Autowired
	private FileService fileService;

	public List<ProductGroup> getProductGroupAsClientMenu() {
		List<com.vietnam.power.persitence.ProductGroup> pgs = productDao.getProductGroupAsClientMenu();
		Iterator<com.vietnam.power.persitence.ProductGroup> itr = pgs.iterator();

		while (itr.hasNext()) {
			com.vietnam.power.persitence.ProductGroup pg = itr.next();
			// remove sub-menu, menu level = 2
			if (CollectionUtils.isNotEmpty(pg.getSubProductGroups1())) {
				itr.remove();
			}
		}

		return convertToDomainList(pgs);
	}

	private List<ProductGroup> convertToDomainList(List<com.vietnam.power.persitence.ProductGroup> pgs) {
		List<ProductGroup> lst = new ArrayList<ProductGroup>();
		for (com.vietnam.power.persitence.ProductGroup pg : pgs) {
			ProductGroup dpg = new ProductGroup();
			dpg.convertToDomain(pg);
			lst.add(dpg);
		}
		return lst;
	}

	public List<Product> searchProductByCriteria(ProductSearchCriteria psc, Integer page) {
		if (page == null) {
			page = 1;
		}

		int max = applicationDao.getAppConfigurationByName(AppConfigurationConstant.APP_CONFIGURATION.MAX_RECORDS_PER_PAGE).getThreshold();
		if (psc != null && psc.getMax() != null) {
			max = psc.getMax();
		}
		int totalProduct = productDao.totalProduct(psc);
		long totalPage = (long) Math.ceil(totalProduct / (double) max);

		List<Product> lst = new ArrayList<Product>();

		for (com.vietnam.power.persitence.Product p : productDao.getAllProductList(psc, page, max)) {
			Product pd = new Product();
			pd.convertToDomain(p);
			pd.setTotalPage(totalPage);
			lst.add(pd);
		}

		return lst;
	}

	public Product getProductById(int pId) {
		Product pd = new Product();
		pd.convertToDomain(productDao.getProductById(pId));

		return pd;
	}

	public void createProductGroup(ProductGroup pg) {
		com.vietnam.power.persitence.ProductGroup ppg = new com.vietnam.power.persitence.ProductGroup();
		pg.convertToPersist(ppg);
		if (CollectionUtils.isNotEmpty(pg.getParentProductGroupList())) {
			SubProductGroup spg = new SubProductGroup();
			spg.setProductGroup1(ppg);
			spg.setProductGroup2(new com.vietnam.power.persitence.ProductGroup(pg.getParentProductGroupList().get(0).getId()));

			ppg.addSubProductGroups1(spg);
		}

		productDao.createProductGroup(ppg);
		// set id
		pg.setId(ppg.getId());
	}

	public ProductGroup getProductGroupById(int id) {
		com.vietnam.power.persitence.ProductGroup ppg = productDao.getProductGroupById(id);
		ProductGroup dpg = new ProductGroup();
		dpg.convertToDomain(ppg);
		return dpg;
	}

	public void updateProductGroup(ProductGroup pg) {
		com.vietnam.power.persitence.ProductGroup ppg = productDao.getProductGroupById(pg.getId());
		pg.convertToPersist(ppg);

		if (CollectionUtils.isEmpty(pg.getParentProductGroupList())) {
			ppg.getSubProductGroups1().clear();
		} else {
			if (CollectionUtils.isEmpty(ppg.getSubProductGroups1())) {
				SubProductGroup spg = new SubProductGroup();
				spg.setProductGroup1(ppg);
				spg.setProductGroup2(new com.vietnam.power.persitence.ProductGroup(pg.getParentProductGroupList().get(0).getId()));

				ppg.addSubProductGroups1(spg);
			} else {
				for (SubProductGroup child : ppg.getSubProductGroups1()) {
					if (child.getProductGroup2().getId() != pg.getParentProductGroupList().get(0).getId()) {
						child.setProductGroup2(new com.vietnam.power.persitence.ProductGroup(pg.getParentProductGroupList().get(0).getId()));
					}
				}
			}
		}

		productDao.updateProductGroup(ppg);
	}

	public void deleteProductGroup(int id) {
		com.vietnam.power.persitence.ProductGroup ppg = productDao.getProductGroupById(id);

		productDao.deleteProductGroup(ppg);
	}

	public void createProduct(Product p) {
		com.vietnam.power.persitence.Product pp = new com.vietnam.power.persitence.Product();
		p.convertToPersist(pp);

		for (Integer i : p.getProductImages()) {
			ProductImage pi = new ProductImage();
			pi.setFileUpload(new FileUpload(i));
			pi.setProduct(pp);

			pp.addProductImage(pi);
			fileService.updateFileStatusToActive(i,null);
		}

		productDao.createProduct(pp);
		//return id
		p.setId(pp.getId());
	}

	public List<Integer> updateProduct(Product p) {
		com.vietnam.power.persitence.Product pp = productDao.getProductById(p.getId());
		p.convertToPersist(pp);

		List<Integer> deletedFileIds = new ArrayList<Integer>();
		Iterator<ProductImage> itr = pp.getProductImages().iterator();

		while (itr.hasNext()) {
			ProductImage i = itr.next();
			if (p.getProductImages().contains(i.getFileUpload().getId())) {
				p.getProductImages().remove(Integer.valueOf(i.getFileUpload().getId()));
			} else {
				deletedFileIds.add(i.getFileUpload().getId());
				itr.remove();
			}
		}

		for (Integer i : p.getProductImages()) {
			ProductImage pi = new ProductImage();
			pi.setFileUpload(new FileUpload(i));
			pi.setProduct(pp);

			pp.addProductImage(pi);
			fileService.updateFileStatusToActive(i,null);
		}

		productDao.updateProduct(pp);
		
		return deletedFileIds;
	}

	public List<Integer>  deleteProduct(int id) {
		List<Integer> deletedFileIds = new ArrayList<Integer>();
		com.vietnam.power.persitence.Product p = productDao.getProductById(id);
		productDao.deleteProduct(p);
		// delete image file here
		for (ProductImage pi : p.getProductImages()) {
			deletedFileIds.add(pi.getFileUpload().getId());
		}
		
		return deletedFileIds;
	}

	public List<ProductGroup> searchProductGroup(ProductGroupSearchCriteria s) {
		List<com.vietnam.power.persitence.ProductGroup> pgs = productDao.searchProductGroup(s);
		
		return convertToDomainList(pgs);
	}

	public List<Product> searchProduct(ProductSearchCriteria s) {
		List<Product> lst = new ArrayList<Product>();

		for (com.vietnam.power.persitence.Product p : productDao.searchProduct(s)) {
			Product pd = new Product();
			pd.convertToDomain(p);
			lst.add(pd);
		}

		return lst;
	}
}
